/*
 * Byte.cpp
 *
 *  Created on: 07/06/2014
 *      Author: manuel
 */

#include "Byte.h"

Byte::Byte() : posicion(0) , lleno(false) {
	bits.reset();
}

Byte::Byte(std::string bits_ini) : bits(bits_ini) , posicion(0), lleno(false) {
}

Byte::~Byte() {}

void Byte::setValor(unsigned char byte){
	std::bitset<8> aux( byte );

	bits.reset();
	bits|=aux;
	lleno = true;
	posicion = 8;
}

bool Byte::cargarDesde(std::fstream& archivo) {
	unsigned char byte;

	archivo.read((char*)&byte, 1);

	std::bitset<8> aux( byte );

	bits.reset();
	bits|=aux;
	lleno = true;
	posicion = 8;

	printf("byte leido: %c, %d\n", byte, (int)bits.to_ulong());

	if (archivo.fail()) {
		archivo.clear();
		return false;
	}
	return true;
}

bool Byte::escribirEn(std::fstream& archivo) {
	unsigned char byte = (unsigned char) bits.to_ulong();

	archivo.write((char*) &byte, 1);
	archivo.flush();

	if (archivo.fail()) {
		archivo.clear();
		return false;
	}
	return true;
}

void Byte::cargarDesdeBloque(unsigned char* posicion_bloque) {
	unsigned char byte;

	memcpy(&byte, posicion_bloque, 1);

	std::bitset<8> aux( byte );

	bits.reset();
	bits|=aux;
	lleno = true;
	posicion = 8;
}

void Byte::escribirEnBloque(unsigned char *posicion_bloque) {
	unsigned char byte = (unsigned char) bits.to_ulong();

	memcpy(posicion_bloque, &byte, 1);
}

void Byte::resetear() {
	bits.reset();
	posicion = 0;
	lleno = false;
}

int Byte::bitsLibres() {
	return 8-posicion;
}

unsigned char Byte::valor() {
	return (unsigned char) bits.to_ulong();
}

std::string Byte::string(){
	return bits.to_string();
}

bool Byte::push_bits(std::string pBits) {
	if( pBits.size() > (unsigned)8-posicion )
		return false;

	for( unsigned short i = 0; i<pBits.size(); i++) {
		char aux = pBits.at(i);
//		printf("pBits[%d]: %d, %c, posicion en bitsset: %d\n", i, atoi( &aux ), pBits.at(i) , 7-posicion-i);
		bits.set( 7-(i+posicion) , (bool) atoi( &aux) );
	}

	posicion += pBits.size();
	//printf("posicion: %d\n", posicion);
	if( posicion == 8 )
		lleno = true;
	return true;
}

bool Byte::pop_bits(std::string &pBits, unsigned short cantidad) {
//	if( posicion - cantidad + 1 == 0)
//		return false;
	if( posicion == 0 )
		return false;

	unsigned short pos = posicion;

	pBits.resize(cantidad);

	//printf("posicion: %d\n", pos);

	for ( unsigned short i = 0; i < cantidad ; i++){
		if( lleno ){
			pos--;
			lleno=false;
		}

		if( bits[posicion-i-1] )
			pBits[pBits.size()-i-1] = '1';
		else
			pBits[pBits.size()-i-1] = '0';
	}

	posicion -= cantidad;

	return true;
}


